Expression Slots
Video Summary
- In JSX, the content we put between open/close tags is treated as a static string. If we try and reference a variable, it'll print the variable name itself, rather than the value it references.
- We can create expression slots with curly brackets (
{}
). Anything placed in-between curly brackets will be treated as pure JavaScript, instead of a string. - There aren't a lot of rules when it comes to JSX. The compilation process doesn't check if it's even valid! It's the messenger; it forwards the content along to the pure JS output.
- Because JSX turns into
React.createElement()
function calls, we'll get a JavaScript syntax error if we try and place a statement in that slot. It has to be an expression.
For more information about the difference between statements and expressions, check out the “Statements Vs. Expressions” lesson 👀 from the JavaScript Primer module.
Here's the sandbox from the video above:
Code Playground
To add a comment in JSX, we use an expression slot:
const element = ( <div> {/* Some comment! */} </div>);
We specifically need to use the multi-line comment syntax (/* */
) instead of the single-line syntax (//
). This is because the single-line syntax comments everything out, including the closing }
for the expression slot!
Attribute expression slots
We can use the same trick for dynamic attribute values!
Here's an example:
const uniqueId = 'content-wrapper';
const element = ( <main id={uniqueId}> Hello World </main>);
As we saw above, the squiggly brackets ({}
) allow us to create an expression slot. This time, we're creating a slot for the value of the id
attribute.
Here's how it compiles:
const element = React.createElement( 'main', { id: uniqueId, }, 'Hello World');
For comparison, here's what it looks like without an expression slot, when the value for id
is fixed:
const element = ( <main id="content-wrapper"> Hello World </main>);
const compiledElement = React.createElement( 'main', { id: "content-wrapper", }, 'Hello World');
We can use attribute expression slots whenever we need the values to be dynamic. We can put any valid JavaScript expression in here, not just variables:
const userEmail = 'sumeet@thegreat.com';
const element = ( <main id={userEmail.replace('@', '-')}> Hello World </main>);
// Will get compiled as:const compiledElement = React.createElement( 'main', { id: userEmail.replace('@', '-'), }, 'Hello World');
Note that when we compile the code, it doesn't actually get evaluated. We've written some logic which will turn that userEmail
string into "sumeet-thegreat.com"
, replacing the @
character with a -
, but that only happens when we run the code.
When JSX gets compiled to JS, we copy over everything between the {
and }
. We don't call any functions or run any of the logic. That happens later, when the processed JavaScript runs in the browser.
This is the distinction between compile-time (the code processing that happens before the code runs in the browser) and run-time (the code execution that happens in the browser).
Type coercion
At run-time, React will automatically convert types as needed when supplying attributes in expression slots.
For example, these two elements are identical:
// This works:<input required="true" />
// And so does this!<input required={true} />
In the first example, we're setting the required
attribute equal to the string "true"
. In the second example, it's equal to the boolean attribute true
. In HTML, values must be strings, and so the boolean true
is converted to the string "true"
.
Similarly, we can pass either numbers or strings for numeric attributes:
// ✅ Valid<input type="range" min="1" max="20" />// ✅ Valid<input type="range" min={1} max={20} />
Comments in JSX